package dao;

import hbt.HibernateUtil;

import java.util.ArrayList;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;

import entidades.Obrero;
import entidades.Proyecto;
import entidades.Rubro;
import entidades.Tarea;
import excepciones.NoSeEncontraronObrerosException;



public class ObreroDAO {
	
	private static ObreroDAO instancia = null;
	private static SessionFactory sf = null;
	
	public static ObreroDAO getInstancia(){
		if(instancia == null){
			sf = HibernateUtil.getSessionFactory();
			instancia = new ObreroDAO();
		} 
		return instancia;
	}
	
	public void guardarUnObrero(Obrero obrero){
		Session session = sf.openSession();
		session.beginTransaction();
		session.saveOrUpdate(obrero); 
		session.getTransaction().commit();
		session.close();
	}
	
	@SuppressWarnings("unchecked")
	public List<Obrero> obtenerListaObreros() throws NoSeEncontraronObrerosException,Exception {
		try {
			Session session = sf.openSession();
			Query q = session.createQuery("from Obrero");
			List<Obrero> listaObreros = new ArrayList<Obrero>(q.list());
			session.close();
			if(listaObreros.isEmpty()){
				throw new NoSeEncontraronObrerosException();
			}
			return listaObreros;
		} catch (Exception e) {
			throw e;
		}
	}
	
	@SuppressWarnings("unchecked")
	public List<Obrero> obtenerListaObrerosPorProyecto(Proyecto p) throws NoSeEncontraronObrerosException, Exception {
		try {
			Session session = sf.openSession();
			Query q = session.createQuery("from Obrero where ID_PROYECTO = "+p.getIdProyecto());
			List<Obrero> listaObreros = new ArrayList<Obrero>(q.list());
			session.close();
			if(listaObreros.isEmpty()){
				throw new NoSeEncontraronObrerosException();
			}
			return listaObreros;
		} catch (Exception e) {
			throw e;
		}
	}
	
	public void bajaObrero(Obrero o) throws Exception {
		try {
			Session session = sf.openSession();
			session.delete(o);
			session.close();
		} catch (Exception e) {
			throw e;
		}
		
	}

	@SuppressWarnings("unchecked")
	public float obtenerScoring(Obrero obreroSeleccionado) {
		float score;
		Session session = sf.openSession();
		Query q = session.createQuery("from Obrero where ID_OBRERO = "+obreroSeleccionado.getIdObrero());
		List<Obrero> listaObreros = new ArrayList<Obrero>(q.list());
		score = listaObreros.get(0).getScoring();
		session.close();
		return score;
	}

	public void updateObrero(Obrero obrero) {
		Session session = sf.openSession();
		session.beginTransaction();
		session.update(obrero);
		session.getTransaction().commit();
		session.close();
		
	}
	
	@SuppressWarnings("unchecked")
	public List<Obrero> obtenerListaObrerosDisponiblesPorRubro(Rubro rubro) throws  NoSeEncontraronObrerosException, Exception {
		try {
			Session session = sf.openSession();
			
			Criteria crit = session.createCriteria(Obrero.class).add(Restrictions.eq("rubro.idRubro", rubro.getIdRubro()))
			.add(Restrictions.isNull("proyecto"))
			.addOrder(Order.desc("scoring"));
			
			List<Obrero> listaObreros = crit.list();	
			if(listaObreros.isEmpty()){
				throw new NoSeEncontraronObrerosException();
			}
			
			session.close();
			return listaObreros;
		} catch (Exception e) {
			throw e;
		}
	}
	
	@SuppressWarnings("unchecked")
	public List<Obrero> obtenerListaObrerosDisponiblesPorTarea(Tarea tarea) throws  NoSeEncontraronObrerosException, Exception {
		try {
			Session session = sf.openSession();			
			Query q1 = session.createSQLQuery(
					" select * from Obreros " +
					" where ID_RUBRO = (" +
						" select id_rubro " +
						" from tareas where " +
						" id_tarea = "+tarea.getIdTarea()+" )" +
					" and id_proyecto is null" +
					" order by scoring desc").addEntity(Obrero.class);	
			List<Obrero> listaObreros = new ArrayList<Obrero>(q1.list());  

			if(listaObreros.isEmpty()){
				throw new NoSeEncontraronObrerosException();
			}
			session.close();
			return listaObreros;
		} catch (Exception e) {
			throw e;
		}
	}
	
	public void liberarObreros(Proyecto proyecto) throws Exception {
		try {
			Session session = sf.openSession();
			Query q = session.createQuery("update Obrero set ID_PROYECTO = null where ID_PROYECTO = "+proyecto.getIdProyecto());
			q.executeUpdate();
			session.close();
		} catch (Exception e) {
			throw e;
		}
		
	}
	
	
	
}
	

